package com.xplusplus.security.service;

import com.xplusplus.security.domain.TemporaryProjectHeader;
import com.xplusplus.security.domain.User;
import com.xplusplus.security.exception.EnumExceptions;
import com.xplusplus.security.exception.SecurityExceptions;
import com.xplusplus.security.repository.DepartmentRepository;
import com.xplusplus.security.repository.TemporaryProjectHeaderRepository;
import com.xplusplus.security.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * @Author: zhouweixin
 * @Description:
 * @Date: Created in 11:17 2018/9/4
 * @Modified By:
 */
@Service
public class TemporaryProjectHeaderService {

    @Autowired
    private TemporaryProjectHeaderRepository temporaryProjectHeaderRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DepartmentRepository departmentRepository;

    /**
     * 新增
     *
     * @param header
     * @return
     */
    public TemporaryProjectHeader add(TemporaryProjectHeader header) {

        // 验证是否存在
        if (header == null || (header.getId() != null
                && temporaryProjectHeaderRepository.findOne(header.getId()) != null)) {
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_DUPLICATE);
        }

        // 验证申请人是否存在
        if (header.getApplicant() == null || header.getApplicant().getId() == null || userRepository.findOne(header.getApplicant().getId()) == null) {
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_APPLY_USER_NOT_EXIST);
        }

        // 验证经办人是否存在
        if (header.getOperator() == null || header.getOperator().getId() == null || userRepository.findOne(header.getOperator().getId()) == null) {
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_OPERATOR_NOT_EXIST);
        }

        // 验证审核人是否存在
        if (header.getAuditor() == null || header.getAuditor().getId() == null || userRepository.findOne(header.getAuditor().getId()) == null) {
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_AUDITOR_NOT_EXISTS);
        }

        // 验证部门是否存在
        if (header.getDepartment() == null || header.getDepartment().getId() == null || departmentRepository.findOne(header.getDepartment().getId()) == null) {
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_DEPARTMENT_NOT_EXIST);
        }

        return temporaryProjectHeaderRepository.save(header);
    }

    /**
     * 更新
     *
     * @param header
     * @return
     */
    @Transactional
    public TemporaryProjectHeader update(TemporaryProjectHeader header) {
        if (header == null || header.getId() == null || temporaryProjectHeaderRepository.findOne(header.getId()) == null) {
            throw new SecurityExceptions(EnumExceptions.UPDATE_FAILED_NOT_EXIST);
        }
        // 删除
        temporaryProjectHeaderRepository.delete(header.getId());

        // 重新新增
        return this.add(header);
    }

    /**
     * 查询所有-分页
     *
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    public Page<TemporaryProjectHeader> getAllByPage(Integer page, Integer size, String sortFieldName, Integer asc) {
        // 判断排序字段名是否存在
        try {
            TemporaryProjectHeader.class.getDeclaredField(sortFieldName);
        } catch (Exception e) {
            // 如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort = null;
        if (asc == 0) {
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        } else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);
        return temporaryProjectHeaderRepository.findAll(pageable);
    }

    /**
     * 通过申请人, 状态和日期段查询-分页
     *
     * @param startDate
     * @param endDate
     * @param applicantId
     * @param status
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    public Page<TemporaryProjectHeader> getByApplicantAndStatusAndDateByPage(Date startDate, Date endDate, String applicantId, Integer status, Integer page, Integer size, String sortFieldName, Integer asc) {
        // 判断排序字段名是否存在
        try {
            TemporaryProjectHeader.class.getDeclaredField(sortFieldName);
        } catch (Exception e) {
            // 如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort = null;
        if (asc == 0) {
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        } else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);

        User applicant = new User();
        applicant.setId(applicantId);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean b1 = "2000-01-01".equals(sdf.format(startDate)) || "2000-01-01".equals(sdf.format(endDate));
        boolean b2 = applicantId.equals("-1");
        boolean b3 = status == -1;

        if (!b1 && b2 && b3) {
            return temporaryProjectHeaderRepository.findByDateBetween(startDate, endDate, pageable);
        } else if (b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByApplicant(applicant, pageable);
        } else if (b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatus(status, pageable);
        } else if (!b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByApplicantAndApplyTimeBetween(applicant, startDate, endDate, pageable);
        } else if (!b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatusAndApplyTimeBetween(status, startDate, endDate, pageable);
        } else if (b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByApplicantAndStatus(applicant, status, pageable);
        } else if (!b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByApplicantAndStatusAndApplyTimeBetween(applicant, status, startDate, endDate, pageable);
        }

        return temporaryProjectHeaderRepository.findAll(pageable);
    }

    /**
     * 通过经办人和日期段查询-分页
     *
     * @param startDate
     * @param endDate
     * @param operatorId
     * @param status
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    public Page<TemporaryProjectHeader> getByOperatorAndStatusAndDateByPage(Date startDate, Date endDate, String operatorId, Integer status, Integer page, Integer size, String sortFieldName, Integer asc) {
        // 判断排序字段名是否存在
        try {
            TemporaryProjectHeader.class.getDeclaredField(sortFieldName);
        } catch (Exception e) {
            // 如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort = null;
        if (asc == 0) {
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        } else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);

        User operator = new User();
        operator.setId(operatorId);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean b1 = "2000-01-01".equals(sdf.format(startDate)) || "2000-01-01".equals(sdf.format(endDate));
        boolean b2 = operatorId.equals("-1");
        boolean b3 = status == -1;

        if (!b1 && b2 && b3) {
            return temporaryProjectHeaderRepository.findByDateBetween(startDate, endDate, pageable);
        } else if (b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByOperator(operator, pageable);
        } else if (b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatus(status, pageable);
        } else if (!b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByOperatorAndApplyTimeBetween(operator, startDate, endDate, pageable);
        } else if (!b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatusAndApplyTimeBetween(status, startDate, endDate, pageable);
        } else if (b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByOperatorAndStatus(operator, status, pageable);
        } else if (!b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByOperatorAndStatusAndApplyTimeBetween(operator, status, startDate, endDate, pageable);
        }

        return temporaryProjectHeaderRepository.findAll(pageable);
    }

    /**
     * 通过审核人和日期段查询-分页
     *
     * @param startDate
     * @param endDate
     * @param auditorId
     * @param status
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    public Page<TemporaryProjectHeader> getByAuditorAndStatusAndDateByPage(Date startDate, Date endDate, String auditorId, Integer status, Integer page, Integer size, String sortFieldName, Integer asc) {
        // 判断排序字段名是否存在
        try {
            TemporaryProjectHeader.class.getDeclaredField(sortFieldName);
        } catch (Exception e) {
            // 如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort = null;
        if (asc == 0) {
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        } else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);

        User auditor = new User();
        auditor.setId(auditorId);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean b1 = "2000-01-01".equals(sdf.format(startDate)) || "2000-01-01".equals(sdf.format(endDate));
        boolean b2 = auditorId.equals("-1");
        boolean b3 = status == -1;

        if (!b1 && b2 && b3) {
            return temporaryProjectHeaderRepository.findByDateBetween(startDate, endDate, pageable);
        } else if (b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByAuditor(auditor, pageable);
        } else if (b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatus(status, pageable);
        } else if (!b1 && !b2 && b3) {
            return temporaryProjectHeaderRepository.findByAuditorAndApplyTimeBetween(auditor, startDate, endDate, pageable);
        } else if (!b1 && b2 && !b3) {
            return temporaryProjectHeaderRepository.findByStatusAndApplyTimeBetween(status, startDate, endDate, pageable);
        } else if (b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByAuditorAndStatus(auditor, status, pageable);
        } else if (!b1 && !b2 && !b3) {
            return temporaryProjectHeaderRepository.findByAuditorAndStatusAndApplyTimeBetween(auditor, status, startDate, endDate, pageable);
        }

        return temporaryProjectHeaderRepository.findAll(pageable);
    }

    /**
     * 通过主键查询
     *
     * @param id
     * @return
     */
    public TemporaryProjectHeader getById(Long id) {
        return temporaryProjectHeaderRepository.findOne(id);
    }

    /**
     * 通过主键审核
     *
     * @param id
     * @param auditorId
     * @param status
     * @param note
     */
    @Transactional
    public void auditById(Long id, String auditorId, Integer status, String note) {
        TemporaryProjectHeader header = temporaryProjectHeaderRepository.findOne(id);
        if (header == null) {
            throw new SecurityExceptions(EnumExceptions.AUDIT_FAILED_NOT_EXISTS);
        }

        if (header.getStatus() != 0) {
            throw new SecurityExceptions(EnumExceptions.AUDIT_FAILED_AUDITED);
        }

        if (!auditorId.equals(header.getAuditor().getId())) {
            throw new SecurityExceptions(EnumExceptions.AUDIT_FAILED_NOT_CUR_AUDITOR);
        }

        temporaryProjectHeaderRepository.updateStatus(status, new Date(), note, id);
    }

    @Transactional
    public void deleteByIdAndApplicant(Long[] ids, String applicantId) {
        User applicant = new User();
        applicant.setId(applicantId);
        temporaryProjectHeaderRepository.deleteByIdInAndApplicant(Arrays.asList(ids), applicant);
    }
}
